package ase.eleitweg.server.db;

import java.util.*;

import ase.eleitweg.common.Document;
import ase.eleitweg.common.Edge;
import ase.eleitweg.common.Group;
import ase.eleitweg.common.Node;
import ase.eleitweg.common.Run;
import ase.eleitweg.common.User;
import ase.eleitweg.common.Workflow;
import java.io.*;

public class MemoryDB implements ELeitwegDAO {
	
	public MemoryDB() {
		try {
			ObjectInputStream oos = new ObjectInputStream(new FileInputStream(new File(System.getProperty("user.dir") + "/dataTestFilled/TestData.bin")));
			users = (List<User>) oos.readObject();
			groups = (List<Group>) oos.readObject();
			workflows = (List<Workflow>) oos.readObject();
			runs = (List<Run>) oos.readObject();
			documents = (List<Document>) oos.readObject();
			//restore correct doc-references:
			for(Document doc : documents) {
				for(Run r : runs) {
					if(doc.getR().getId() == r.getId()) {
						doc.setR(r);
					}
				}
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private List<User> users;
	
	private List<Workflow> workflows;
	
	
	private List<Group> groups;
	
	private List<Run> runs;
	
	private List<Document> documents;
	
	public Run getInstanceById(int id) {
		for(Run r : runs) {
			if(r.getId() == id) {
				return r;
			}
		}
		return null;
	}
	
	public void deleteDocumentsfromInstance(int id) {
		Iterator<Document> docIt = documents.iterator();
		while(docIt.hasNext()) {
			if(docIt.next().getR().getId() == id) {
				docIt.remove();
			}
		}
	}
	
	public void updateWorkflow(Workflow w) {
		for(Workflow w2 : workflows) {
			if(w2.getWNr() == w.getWNr()) {
				w2.setDate(w.getDate());
				w2.setName(w.getName());
				w2.setDesc(w.getDesc());
			}
		}
	}

	public void addUserToGroup(Group g, User u) {
		for(Group grp : groups) {
			if(g.getId() == grp.getId()) {
				for(User usr : grp.getUsers()) {
					if(u.getId() == usr.getId()) {
						return;
					}
				}
				for(User usr : users) {
					if(u.getId() == usr.getId()) {
						grp.addUser(usr);
					}
				}
			}
		}
	}


	public int createDocument(Document d) {
		int maxid = 0;
		for(Document doc : documents) {
			if(doc.getId() > maxid) {
				maxid = doc.getId();
			}
		}
		d.setId(maxid+1);
		documents.add(d);
		return d.getId();
	}


	
	public int createGroup(Group g) {
		int maxid = 0;
		for(Group grp : groups) {
			if(grp.getId() > maxid) {
				maxid = grp.getId();
			}
		}
		g.setId(maxid+1);
		groups.add(g);
		return g.getId();
	}


	public int createInstance(Run i) {
		int maxid = 0;
		for(Run run : runs) {
			if(run.getId() > maxid) {
				maxid = run.getId();
			}
		}
		i.setId(maxid+1);
		runs.add(i);
		return i.getId();
	}


	
	public int createUser(User u) {
		int maxid = 0;
		for(User usr : users) {
			if(usr.getId() > maxid) {
				maxid = usr.getId();
			}
		}
		u.setId(maxid+1);
		users.add(u);
		return u.getId();
	}

	
	public int createWorkflow(Workflow w) {
		int maxid = 0;
		for(Workflow wf : workflows) {
			if(wf.getWNr() > maxid) {
				maxid = wf.getWNr();
			}
		}
		w.setWNr(maxid+1);
		workflows.add(w);
		return w.getWNr();
	}

	
	public void deleteDocument(Document d) {
		Iterator<Document> dit = documents.iterator();
		while(dit.hasNext()) {
			if(d.getId() == dit.next().getId()) {
				dit.remove();
			}
		}
	}

	
	public void deleteGroup(Group g) {
		Iterator<Group> git = groups.iterator();
		while(git.hasNext()) {
			if(g.getId() == git.next().getId()) {
				git.remove();
			}
		}
	}

	
	public void deleteInstance(Run i) {
		Iterator<Run> rit = runs.iterator();
		while(rit.hasNext()) {
			if(i.getId() == rit.next().getId()) {
				rit.remove();
			}
		}
		Iterator<Document> dit = documents.iterator();
		while(dit.hasNext()) {
			if(dit.next().getR().getId() == i.getId()) {
				dit.remove();
			}
		}
	}

	
	public void deleteUser(User u) {
		Iterator<User> uit = users.iterator();
		while(uit.hasNext()) {
			if(u.getId() == uit.next().getId()) {
				uit.remove();
			}
		}
		for(Group g : groups) {
			Iterator<User> guit = g.getUsers().iterator();
			while(guit.hasNext()) {
				if(u.getId() == guit.next().getId()) {
					guit.remove();
				}
			}
		}
	}

	
	public void deleteUserGroup(Group g, User u) {
		for(Group grp : groups) {
			if(grp.getId() == g.getId()) {
				Iterator<User> guit = grp.getUsers().iterator();
				while(guit.hasNext()) {
					if(u.getId() == guit.next().getId()) {
						guit.remove();
					}
				}
			}
		}
	}

	
	public void deleteWorkflow(Workflow w) {
		Iterator<Workflow> wIt = workflows.iterator();
		while(wIt.hasNext()) {
			if(wIt.next().getWNr() == w.getWNr()) {
				wIt.remove();
			}
		}
	}

	
	public List<Workflow> getAllWorkflows() {
		return new Vector<Workflow>(workflows);
	}

	
	public List<Document> getDocuments(int runId) {
		List<Document> result = new Vector<Document>();
		for(Document d : documents) {
			if(d.getR().getId() == runId) {
				result.add(d);
			}
		}
		return result;
	}

	
	public Group getGroupById(int id) {
		for(Group g : groups) {
			if(g.getId() == id) {
				return g;
			}
		}
		return null;
	}

	
	public List<Group> getGroups() {
		return new Vector<Group>(groups);
	}

	
	public List<Run> getInstances(int wnr) {
		List<Run> result = new Vector<Run>();
		for(Run r : runs) {
			if(r.getWf().getWNr() == wnr) {
				result.add(r);
			}
		}
		return result;
	}

	
	public List<Run> getInstances(int wnr, int anr) {
		List<Run> result = new Vector<Run>();
		for(Run r : runs) {
			if(r.getWf().getWNr() == wnr && r.getNode().getId() == anr) {
				result.add(r);
			}
		}
		return result;
	}

	
	public List<Run> getInstances() {
		return new Vector<Run>(runs);
	}

	
	public User getUserById(int id) {
		for(User u : users) {
			if(u.getId() == id) {
				return u;
			}
		}
		return null;
	}

	
	public List<User> getUsers() {
		return new Vector<User>(users);
	}

	
	public List<Group> getUsersGroups(User u) {
		List<Group> result = new Vector<Group>();
		for(Group grp : groups) {
			for(User usr : grp.getUsers()) {
				if(u.getId() == usr.getId()) {
					result.add(grp);
				}
			}
		}
		return result;
	} 

	
	public List<User> getUsersOfGroup(Group g) {
		for(Group grp : groups) {
			if(g.getId() == grp.getId()) {
				return grp.getUsers();
			}
		}
		return null;
	}

	
	public Workflow getWorkflow(int wnr) {
		for(Workflow w : workflows) {
			if(w.getWNr() == wnr) {
				return w;
			}
		}
		return null;
	}

	
	public void updateGroup(Group g) {
		for(Group grp : groups) {
			if(grp.getId() == g.getId()) {
				grp.setName(g.getName());
			}
		}
	}

	
	public void updateInstance(Run i) {
		for(Run rx : runs) {
			if(rx.getId() == i.getId()) {
				for(User ux : users) {
					if(ux.getId() == i.getUser().getId()) {
						rx.setUser(ux);
					}
				}
				rx.setDate(i.getDate());
				rx.setAccepted(i.isAccepted());
				rx.setNode(i.getNode());
			}
		}
	}

	
	public void updateUser(User u) {
		for(User usr : users) {
			if(usr.getId() == u.getId()) {
				usr.setEmail(u.getEmail());
				usr.setFirstname(u.getFirstname());
				usr.setSurname(u.getSurname());
				usr.setPasswdhash(u.getPasswdhash());
				usr.setPhone(u.getPhone());
				usr.setType(u.getType());
				usr.setUsername(u.getUsername());
			}
		}
	}
	
	
	public List<Document> getDocumentWithoutData(int runId) {
		List<Document> result = new Vector<Document>();
		for(Document d : documents) {
			if(d.getR().getId() == runId) {
				result.add(d);
			}
		}
		return result;
	}
	
	public void destroy() {
		
	}


}
